package com.yjb.tenet.boot.common.pojo;

import com.yjb.tenet.boot.common.exception.CustomException;
import com.yjb.tenet.boot.common.exception.enums.ErrorCodeEnum;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import java.util.Objects;

/**
 * @Description 通用的返回对象
 * @Author yin.jinbiao
 * @Date 2021/10/12 13:38
 * @Version 1.0
 */
@Data
public class ResponseResult<T> {

    /**
     * 状态码
     */
    private String code;

    /**
     * 消息
     */
    private String msg;

    /**
     * 返回对象
     */
    private T data;

    public static <T> ResponseResult<T> ok(){
        return newResponse(ErrorCodeEnum.SUCCESS.getCode(), ErrorCodeEnum.SUCCESS.getMsg(), null);
    }

    public static <T> ResponseResult<T> ok(T data){
	    return newResponse(ErrorCodeEnum.SUCCESS.getCode(), ErrorCodeEnum.SUCCESS.getMsg(), data);
    }

	public static ResponseResult error(String code, String msg){
		return newResponse(code, msg, null);
	}

    public static <T> ResponseResult<T> newResponse(String code, String msg, T data) {
        ResponseResult<T> result = new ResponseResult<T>();
        result.setCode(code);
        result.setMsg(msg);
        if (data != null && data instanceof String && "".equals(data)) {
            result.setData(null);
        } else {
            result.setData(data);
        }
        return result;
    }

	@JsonIgnore // 避免 jackson 序列化
	public boolean isSuccess() {
		return isSuccess(code);
	}

	@JsonIgnore // 避免 jackson 序列化
	public boolean isError() {
		return !isSuccess();
	}

	public static boolean isSuccess(String code) {
		return Objects.equals(code, ErrorCodeEnum.SUCCESS.getCode());
	}

	// ========= 和 Exception 异常体系集成 =========

	/**
	 * 判断是否有异常。如果有，则抛出 {@link CustomException} 异常
	 */
	public void checkError() throws CustomException {
		if (isSuccess()) {
			return;
		}
		// 业务异常
		throw new CustomException(code, msg);
	}

	/**
	 * 判断是否有异常。如果有，则抛出 {@link CustomException} 异常
	 * 如果没有，则返回 {@link #data} 数据
	 */
	@JsonIgnore // 避免 jackson 序列化
	public T getCheckedData() {
		checkError();
		return data;
	}

	@Override
	public String toString() {
		return "{\"code\": " + this.getCode() + ", \"msg\": " + this.transValue(this.getMsg()) + ", \"data\": " + this.transValue(this.getData()) + "}";
	}

	private String transValue(Object value) {
		return value instanceof String ? "\"" + value + "\"" : String.valueOf(value);
	}
}
